######################################################## # # # Introduction To Fractal Explorer Formulae Compilator # # version 2.01 # # # ######################################################## Written by Sirotinsky Arthur and Olga Fedorenko WWW http://skyscraper.fortunecity.com/binary/34/index.html EMail art@gor.kv.energy.gov.ua Sorry for any spelling mistakes, our natural language is Russian. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0 Changes. 1 Acknowledgements 2 Limitations 3 Introduction 3.1 What is the formula compilator ? 3.2 Formula Files 4 Formula's Anatomy 4.1 Formula it's a program 4.2 Formula it's a Delphi/Pascal program 4.3 Requirements 4.4 Simple project 4.5 Temporarly variable declaration 4.6 Complicated project 4.7 The complex functions 4.8 Stels compilation 5 Version 2.01 of the compilator 5.1 List of the functions and procedures 5.2 Another changes in version 2.01 5.3 Examples of the new formulaes 0 Changes ============= Version 2.01 of the Formulae Compilator has little but very important changes. First of all, now, you do not needed to write the difficult expressions for the formula realization. We have added support for many operations and functions of the complex values. Also, we added four complex variables for using in your functions. In part number [5] we describe the new possibilities. Please, read it before using Formulae Compilator. 1 Acknowledgements ====================== Bradley Beacham for FRMTUTOR.TXT AN INTRODUCTION TO THE FRACTINT FORMULA PARSER Borland/Inprise/ Corp. for Delphi Command Line compiler 2 Limitations ================= Our formulae compilator is not parser. It's part of the program, which calculated one step of the iteration process. It can't read formulae directly, since complex type is not standard type for Delphi. 3 Introduction ================== 3.1 What is the formula compilator ? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is a new part of the fractal-generating program, Fractal Explorer (version 1.13 and above). FE has many different types of the fractal's formulaes itself, the formula compilator allows you to add new fractals, without having to change the program. These formulaes are stored in Fractal Spot files, and may be viewed and edited by the user. 3.2 Formula Files ~~~~~~~~~~~~~~~~~~~ New user formula are not saved to simple file. Formula will be stored into Fractal Spot file (*.frs), which contains internal data for generating image. Therefore, FE requires one FRS file for building one image (formula already implemented into). 4 Formula's Anatomy ======================= Why compilator ? Compiled programs always work more quickly than interpretator. 4.1 Formula it's a program ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fractal Explorer uses formula's text for building Dynamic Link Libraries (DLL), after that loaded new dll (for interest - look to system TEMP directory - strings "SET TMP=" or "SET TEMP=" in your autoexec.bat). After formula changing (or exit FE) DLL will be unloaded from memory and deleted with the project source. 4.2 Formula it's a Delphi/Pascal program ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To compile a new formula, FE will create the Delphi project file (*.DPR) in the temporary directory and execute Borland Delphi Command Line compiler to generate the DLL file. Since we are using the Delphi for writing Fractal Explorer, we are using Delphi for DLL compilation. 4.3 Requirements ~~~~~~~~~~~~~~~~~~ Using formula compilator in FE required many files. They are listed below: dcc32 exe math dcu sharemem dcu sysinit dcu system dcu sysutils dcu windows dcu rlink32 dll sysutils inc make pif All files must exist in the Fractal Explorer directory. FE will be check for the presence of these files before compiling the new formula. If you lost one or more files - download full archive from: http://skyscraper.fortunecity.com/binary/34/compiler.zip and unzip it into FE's folder. 4.4 Simple project ~~~~~~~~~~~~~~~~~~~~ Complex number are two-part number. First part - real part, and second part - imaginary part. Notation of complex numbers are: Z = X + jY, where "j" - imaginary part sign. Fractal Explorer using such format of complex number. For illustrating of formula take Mandelbroth Set: Traditional Mandelbrot-set: z_new = z * z + c You write in edit box: ---------Cut----Cut---------- var k: Extended; Begin k:=(x+y) * (x-y) + cr; y:=2 * x * y + ci; x:=k; End; ---------Cut----Cut---------- "x" is real part of "z" complex number,  and "y" - imag part. "cr" is real part of "c" complex number,  and "ci" - imag part. "z" value received in "x" and "y" variables. New value of "z" will be returned in these variables. Variable "k" using for store new "x" value before calculating new "y" value. Press "Go" button. FE makes Delphi project for this formula: ---------Cut----Cut---------- library proba; Uses ShareMem, SysUtils, Math, Complex; Procedure Formula(var x, y, cr, ci: Extended; p1r, p1i, p2r, p2i, p3r, p3i: Extended; var cA1, cA2, cA3, cA4: TComplex); export; var k: Extended; Begin k:=(x+y) * (x-y) + cr; y:=2 * x * y + ci; x:=k; End; exports Formula index 1 name 'Formula'; BEGIN END. ---------Cut----Cut--------- For Delphi and Pascal programmers these codes are not difficult. For other people, it will be interesting only in Procedure Formula declaration: Procedure Formula(var x, y, cr, ci: Extended; p1r, p1i, p2r, p2i, p3r, p3i: Extended; var cA1, cA2, cA3, cA4: TComplex); export; Variables x and y - mathematical coordinates of current point on every cycle; cr,ci - real and imag party Julie parameter (C), another sence - Z0 value; p1r..p3i - real and imag party fractal parameters P1, P2 and P3. You can modify values of cr and ci. For example: ---------Cut----Cut--------- var c1,c2: Extended; Begin c1:=x; c2:=y; k:=(x+y) * (x-y) + cr; y:=2 * x * y + ci; x:=k; cr:=c1; ci:=c2; End; ---------Cut----Cut--------- Values, received in p1r, p1i, p2r, p2i, p3r, p3i parameters are real and imag parts of P1, P2 and P3 parameters of the fractal (see "Select formula" window). They are constant for your formula. That's all folks ! NOTE: do not write calculation cycle - Fractal Explorer makes it itself !!! 4.5 Temporary variable declaration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Separate your formula to small parts and use temporary variables (remember, that it requires "var" section); Syntax for a temporary variable declaration: var name1, name2, name3: [type] Type may be "Single", "Double" or "Extended". Difference: type | range | significant digits | size in bytes ---------+-----------------------------+--------------------+-------------- Single | 1.5x10^_45 .. 3.4x10^38 | 7_8 | 4 Double | 5.0x10^_324 .. 1.7x10^308 | 15_16 | 8 Extended | 3.6x10^_4951 .. 1.1x10^4932 | 19_20 | 10 "Single" works quickly, but precision is smallest; "Double" works slow, but precision is good; "Extended" works very slowly, but precision is very good. Examles: var tmp1,tmp2: Double; Begin End; var h1x,h1y: Double; h2x,h2y: Double; Begin End; var h1x,h1y: Double; h2x,h2y: Double; f: Extended; Begin End; 4.6 Difficult project ~~~~~~~~~~~~~~~~~~~~~~~ Mandel/Talis formula: z_new = z*z + c; c_new = c*c/(c+P1) + z_new; Write: ---------Cut----Cut--------- var h1x,h1y, h2x,h2y, f: Extended; // -temporary variables Begin h1x:=(x+y)*(x-y)+cr; // -calculating z_new y := x*y*2 +ci; // z_new = z*z + c x := h1x; h1x:= (cr+ci)*(cr-ci); // -h1 = c*c h1y:= cr*ci * 2; h2x:= cr+p1r; // -h2 = c+P1 h2y:= ci+p1i; f := h2x*h2x+h2y*h2y+1E-25; // -c_new=h1/h2 + z_new cr :=(h2x*h1x+h2y*h1y)/f+x; ci :=(h2x*h1y-h2y*h1x)/f+y; End; ---------Cut----Cut--------- You calculate new values for "x" (real part) and "y" (imag part) of complex variable "z". Also, you change cr and ci values - real and imag parts of "c". Next step will use z_new and c_new. 4.7 The complex functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can insert many complex functions into your formulae, but you may find it necessary to describe them, like that (remember, that Z = X + jY and C = CR + jCI): z*z: X_new := (X-Y)*(X+Y); Y_new := 2 * X*Y; z*c: X_new := X*CR - Y*CI; Y_new := X*CI + Y*CR; z*z*z: X_new := X*(X*X-3*Y*Y); // -this is optimized formula Y_new := Y*(3*X*X-Y*Y); z*z*z*z: tmp_r := (X-Y)*(X+Y); tmp_i := 2 * X*Y; X_new := (tmp_r - tmp_i) * (tmp_r + tmp_i); Y_new := 2 * tmp_r * tmp_i; 1/z: tmp := X*X + Y*Y + 1E-10; // -without 1E-10 may by divizion by zero X_new := X / tmp; Y_new := Y / tmp; 1/(z*z): tmp := X*X + Y*Y; tmp := tmp * tmp + 1E-10; // -without 1E-10 may by divizion by zero X_new := (X*X - Y*Y) / tmp; Y_new := (2*X * Y ) / tmp; Sqrt(z): tmp := Sqrt(X*X + Y*Y); X_new := Sqrt(Abs((X + tmp)/2)); Y_new := Sqrt(Abs((tmp - X)/2)); Exp(z): // e^z tmp := Exp(X); X_new := tmp * Cos(Y); Y_new := tmp * Sin(Y); Exp(1/z): tmp := X*X + Y*Y + 1E-10; // see above s1 := X/tmp; s2 :=-Y/tmp; tmp := Exp(s1); X_new := tmp * Cos(s2); Y_new := tmp * Sin(s2); Ln(z): X_new :=Log2(X*X+Y*Y)/2.7182818285; Y_new :=ArcTan2(Y,X); z^c: h1x :=Log2(X*X+Y*Y)/2.7182818285; // -Ln(z) h1y :=ArcTan2(Y,X); h2x :=h1x*CR - h1y*CI; // -Ln(z)*c h2y :=h1y*CR + h1x*CI; f :=Exp(h2x); // -Exp(Ln(z)*c) X_new :=f*Cos(h2y); Y_new :=f*Sin(h2y); Sin(z): tmp := Exp(Y)/2; // -optimized formula (!) tmp2 := 0.25/tmp; X_new := Sin(X) * (tmp+tmp2); Y_new := Cos(X) * (tmp-tmp2); Cos(z): X_new := Cos(X)*Cosh(Y); // -not optimized formula Y_new :=-Sin(X)*Sinh(Y); Tan(z): // -tangens X_new := Sin(2*X)/(Cos(2*X)+Cosh(2*Y); Y_new := Sin(2*Y)/(Cos(2*X)+Cosh(2*Y); Sinh(z): // -hiperbolic sinus X_new := Sinh(X)*Cos(Y); // -not optimized formula Y_new := Cosh(X)*Sin(Y); Cosh(z): // -hiperbolic cosinus X_new := Cosh(X)*Cos(Y); // -not optimized formula Y_new := Sinh(X)*Sin(Y); You must change X, Y, CR and CI variables to those, which is required by your formula. 4.8 Stels compilation ~~~~~~~~~~~~~~~~~~~~~~~ Make.pif contains preferences to run Borland Delphi Command Line compiler. It references to file MAKE.BAT, but make.bat will be recreated by Fractal Explorer. By default, we specially leave window for completed compilation process: look for errors and warnings about optimization of your formula. You can make any changes in MAKE.PIF (please, keep MAKE.BAT as command line). And you can modify property for automatic closing window after process termination. 5 Version 2.01 of the compilator ==================================== 5.1 List of the functions and procedures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First of all, we want to describe the type of the complex values. This type is declared in Complex.pas as listed below: Type TComplex = record real: Extended; imag: Extended; end; All of the functions listed below will use this type for their operations. It's a very important part of the new version Formulae Compilator. List of the functions and procedures #################################### I. Function MakeComplex(real, imag: Extended): TComplex; This function makes TComplex value from the two values, which describes the real and imag part of the complex value. Use this function to translate the input values (x,y, cr,ci and p1r..p3i) to the complex type. After this translation you can use result in other functions and procedures. Also, you can use this function to make TComplex value from constant, for example: tmp:=MakeComplex(3,0) - make real numeric "3" as TComplex. II. Procedure SetResult(var x,y: Extended; const complex: TComplex); This procedure makes final results accessible for Formulae Compilator. As described in [4.4] part of this, result values must be returned in the "X" and "Y" variables. You can use two operations for it: x:=Z.real; y:=Z.imag; but now you can use the SetResult procedure for this. | Below are listed functions and procedures for mathematical operations. | Every operation has two releases. First - as procedure with no result | returning and second - as function, which returns the result of the | operation as TComplex value. Any procedure keeps the result complex | value in the variable, which passed as the first parameter. III. Sum of the two complex: Procedure CAddV(var Cmp1: TComplex; const Cmp2: TComplex); Cmp1 := Cmp1 + Cmp2; Result value will be returned in the "Cmp1" variable. Function CAdd (const Cmp1, Cmp2: TComplex): TComplex; Cmp3 := Cmp1 + Cmp2; Result value will be returned as a result of the function. IV. Subtraction of the two complex: Procedure CSubV(var Cmp1: TComplex; const Cmp2: TComplex); Cmp1 := Cmp1 - Cmp2; Function CSub (const Cmp1, Cmp2: TComplex): TComplex; Cmp3 := Cmp1 - Cmp2; V. Multiplication of the two complex: Procedure CMulV(var Cmp1: TComplex; const Cmp2: TComplex); Cmp1 := Cmp1 * Cmp2; Function CMul (const Cmp1, Cmp2: TComplex): TComplex; Cmp3 := Cmp1 * Cmp2; VI. Division of the two complex: Procedure CDivV(var Cmp1: TComplex; const Cmp2: TComplex); Cmp1 := Cmp1 / Cmp2; Function CDiv (const Cmp1, Cmp2: TComplex): TComplex; Cmp3 := Cmp1 / Cmp2; | Next set of the functions realizes the optimized functions VII. Square of the complex: Procedure CSqrV(var Cmp1: TComplex); Cmp1 := Cmp1^2; Function CSqr (Cmp1: TComplex): TComplex; Cmp2 := Cmp1^2; VIII. Third power of the complex: Procedure CTripleV(var Cmp1: TComplex); Cmp1 := Cmp1^3; Function CTriple (Cmp1: TComplex): TComplex; Cmp2 := Cmp1^3; IX. Fourth power of the complex: Procedure CFourV(var Cmp1: TComplex); Cmp1 := Cmp1^4; Function CFour (Cmp1: TComplex): TComplex; Cmp2 := Cmp1^4; X. Flip of the complex: Procedure CFlipV(var Cmp1: TComplex); Cmp1.real:=Cmp1.imag Cmp1.imag:=Cmp1.real Function CFlip (Cmp1: TComplex): TComplex; Cmp2.real:=Cmp1.imag Cmp2.imag:=Cmp1.real XI. Reversing of the complex: Procedure CRevV (var Cmp1: TComplex); Cmp1 := 1 / Cmp1; Function CRev (const Cmp1: TComplex): TComplex; Cmp1 := 1 / Cmp1; XII. Another reversing: Procedure CRev2V(var Cmp1: TComplex; Cmp2: TComplex); Cmp1 := 1 / (Cmp1 - Cmp2); Function CRev2 (Cmp1,Cmp2: TComplex): TComplex; Cmp3 := 1 / (Cmp1 - Cmp2); XIII. Squre root of the complex: Procedure CSqrtV(var Cmp1: TComplex); Cmp1 := Sqrt(Cmp1); Function CSqrt (Cmp1: TComplex): TComplex; Cmp2 := Sqrt(Cmp1); XIV. Exponent of the complex: Procedure CExpV (var Cmp1: TComplex); Cmp1 := Exp(Cmp1); Function CExp (Cmp1: TComplex): TComplex; Cmp2 := Exp(Cmp1); XIV. Logorithm of the complex: Procedure CLnV (var Cmp1: TComplex); Cmp1 := Ln(Cmp1); Function CLn (Cmp1: TComplex): TComplex; Cmp2 := Ln(Cmp1); XV. Raise complex to complex power: Procedure CPowerV(var Cmp1: TComplex; Cmp2: TComplex); Cmp1 := Cmp1^Cmp2; Function CPower (Cmp1,Cmp2: TComplex): TComplex; Cmp3 := Cmp1^Cmp2; | Trigonometric functions XVI. Sinus of the complex: Procedure CSinV (var Cmp1: TComplex); Cmp1 := Sin(Cmp1); Function CSin (Cmp1: TComplex): TComplex; Cmp2 := Sin(Cmp1); XVII. Cosinus of the complex: Procedure CCosV (var Cmp1: TComplex); Cmp1 := Cos(Cmp1); Function CCos (Cmp1: TComplex): TComplex; Cmp2 := Cos(Cmp1); XVIII. Tangens of the complex: Procedure CTanV (var Cmp1: TComplex); Cmp1 := Tan(Cmp1); Function CTan (Cmp1: TComplex): TComplex; Cmp2 := Tan(Cmp1); XIX. Hyperbolic sinus of the complex: Procedure CSinhV(var Cmp1: TComplex); Cmp1:=Sinh(Cmp1) Function CSinh (Cmp1: TComplex): TComplex; Cmp2:=Sinh(Cmp1) XX. Hyperbolic cosinus of the complex: Procedure CConhV(var Cmp1: TComplex); Cmp1:=Cosh(Cmp1) Function CCosh (Cmp1: TComplex): TComplex; Cmp2:=Cosh(Cmp1) 5.2 Another changes in version 2.01 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [+] added four complex variables for using in your formulaes. new declaration of the main procedure listed below: Procedure Formula(var x, y, cr, ci: Extended; p1r, p1i, p2r, p2i, p3r, p3i: Extended; var cA1, cA2, cA3, cA4: TComplex); export; This variables has initialized into zero values, i.e. cA1.real = 0 and cA1.imag = 0 and so on. During calculation of the one point this variables will keep user value. [!] now N/ewton/-Set Method will work properly; 5.3 Examples of the new formulaes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I. Mandelbrot furmula: var Z,Z0: TComplex; Begin Z :=MakeComplex(x,y); // make complex from [x] and [y] variables Z0:=MakeComplex(cr,ci); // make complex from [cr] and [ci] variables Z :=CAdd( CSqr(Z), Z0); // calculate the Mandel SetResult(x,y, Z); // store result to [x] and [y] variables End; II. Mandel/Talis formula: z_new = z*z + c; c_new = c*c/(c+P1) + z_new; Write: ---------Cut----Cut--------- var Z,Z0,P1: TComplex; Begin Z :=MakeComplex(x,y); // make complex from [x] and [y] variables Z0:=MakeComplex(cr,ci); // make complex from [cr] and [ci] variables P1:=MakeComplex(p1r,p1i); // make complex from [p1r] and [p1i] variables Z :=CAdd( CSqr(Z), Z0); // calculates Z_NEW Z0:=CDiv(CSqr(Z0), CAdd(Z0,P1)) // Z' = C*C/(C+P1) Z0:=CAdd(Z0,Z); // C_NEW = Z'+Z_NEW SetResult(cr,ci, Z0); // store C_NEW to [cr] and [ci] variables SetResult(x,y, Z); // store Z_NEW to [x] and [y] variables End; 1999, 2000 Sirotinsky Arthur and Olga Fedorenko Kiev, Ukraine.